#ifndef __OOP_H__
#define __OOP_H__
// 类之间的关系有复合composition, 继承 extension 和委托 aggregation
// 复合 composition
// 复合表示一种has -a 的关系，STL中queue的实现就使用了复合关系.这种结构也被称为adapter模式.
// adapter 适配器模式
// composition 关系下的构造和析构
// 构造由内向外
// container的构造函数首先调用component 的default 构造函数, 然后才执行自己
// 析构由外而内
// container的析构函数首先调用自己，然后再调用component的析构函数.
// 委托 delegation  composition by reference
// 委托将类的定义与类的实现分隔开来,也被称为编译防火墙.
// pimpl 
// file string.hpp
// class StringRep;
// class String {
//     public:
//         String();
//         String(const char* s);
//         String(const String& s);
//         String &operator=(const String& s);
//         ~String();
//     private:
//         StringRep* rep; //pimpl
// }
// file String.cpp
// #include "String.hpp"
// namespace {
//     class StringRep {
//     friend class String;
//      int count;
//      char* sss;
//     };
// }
// inheritance 继承 表示is-a
// 继承有三种：public, protected, privated
// 子类的对象有父类的成分 
// 构造由内而外: 先构造父类，再构造子类 
// 析构由外而内：子类的析构函数先执行自己，然后才调用父类的构造函数
// base class 的dtor 必须是virtual
// 函数继承 继承的是调用权
// 虚函数 只要在任何成员函数前加上virtual关键字
// class Shape {
//     public:
//         virtual void draw() const = 0;
//         virtual void error(const std::string& msg);
//         int objectID() const;
// };
// non-virtual 函数: 你不希望子类重新定义（override,覆盖）它
// virtual 函数: 你希望派生类重新定义(override),且它已有默认定义
// pure virtual 函数：你希望派生类一定要重新定义(override)它，你对它没有默认定义
// Template Method  
#include <iostream>

class Comp {
    public:
    Comp() {
        std::cout << "comp constructor!!!" << std::endl;
    }
    ~Comp() {
        std::cout << "comp destructor!!!" << std::endl;
    }
};

class Base {
    public:
    Base():mp(new(Comp)) {
        std::cout << "base constructor!!!" << std::endl;
    }
    ~Base() {
        std::cout << "base destructor!!!!!" << std::endl;
        delete mp;
    }
    private:
        Comp *mp;
};

class Derived : public Base {
    public:
    Derived() {
        std::cout << "Derived constructor!!!" << std::endl;
    }
    ~Derived() {
        std::cout << "Derived destructor!!!!" << std::endl;
        //delete mp;
    }
    // private:
    //     Comp* mp;
};
//子类既有组合又有继承的情况下，先调用基类的构造函数，再调用组合的构造函数.
// 析构时，先调用子类的析构函数，再调用组合的析构函数，最后调用基类的析构函数.

// Delegation(委托) + Inheritance(继承)
// 使用委托+继承实现Observer模式
// 观察者（Observer）模式的定义：指多个对象间存在一对多的依赖关系，当一个对象的状态发生改变时，所有依赖于它的对象都得到通知并被自动更新。
// 这种模式有时又称作发布-订阅模式、模型-视图模式，它是对象行为型模式。
#include <vector>
class Observer;
class Subject 
{
    int m_value;
    std::vector<Observer*> m_views;
public:
    void attach(Observer* obs)
    {
        m_views.push_back(obs);
    }
    void set_val(int value)
    {
        m_value = value;
        notify();
    }
    void notify()
    {
        for (int i = 0; i < m_views.size(); i++) {
            m_views[i]->update(this, m_views);
        }
    }
};
class Observer
{
    public:
        virtual void update(int value) = 0;
};

class Observer1: public Observer 
{
    int m_div;
    public:
    Observer1(Subject* model, int div)
    {
        model->attach(this);
        m_div = div;
    }
};
// Delegation(委托) + Inheritance(继承) 实现 composite 合成模式
class Component
{
    int value;
public:
    Component(int val) { value = val; }
    virtual void add( Component* ) {}
};
class Primitive: public Component
{
    public:
    Primitive(int val):Component(val) {}
};
class Composite: public Component
{
    std::vector<Component*> c;
public:
    Composite(int val): Component(val) {}
    void add(Component* elem) {
        c.push_back(elem);
    }
};
// Delegation(委托) + Inheritance(继承) 实现 prototype 原型设计模式
// Design Patterns Explained Simply
// 
#endif